﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Reflection;

namespace TimeProject.Engine.Security
{
    /// <summary>
    /// User roles assigned to one user.
    /// </summary>
    public class UserRoles : Collection<UserRole>
    {
        /// <summary>
        /// Checks if the user has the specified role.
        /// </summary>
        /// <param name="role">The user role to check.</param>
        /// <returns>true/false</returns>
        public virtual bool HasRole(UserRole role)
        {
            return Contains(role);
        }

        public static IEnumerable<Tuple<UserRole, UserRoleMetadataAttribute>> GetAll()
        {
            foreach (UserRole role in Enum.GetValues(typeof(UserRole)))
            {
                var member = role.GetType().GetMember(role.ToString()).FirstOrDefault();
                var metadata = member.GetCustomAttribute(typeof (UserRoleMetadataAttribute), false) as UserRoleMetadataAttribute;
                    
                yield return new Tuple<UserRole, UserRoleMetadataAttribute>(role, metadata);
            }
        }

        public static string GetRoleId(UserRole role)
        {
            foreach (var x in GetAll().Where(x => x.Item1 == role))
            {
                return x.Item2.Id;
            }

            throw new InvalidOperationException(string.Format("Could not resolve the id for the role '{0}'.", role));
        }

        public static UserRole GetRole(string id)
        {
            if (id == null)
            {
                throw new ArgumentNullException("id");
            }

            foreach (var x in GetAll().Where(x => x.Item2.Id == id))
            {
                return x.Item1;
            }

            throw new InvalidOperationException(string.Format("Could not resolve the UserRole for the id '{0}'.", id));            
        }

    }
}
